package com.iot.lemon.web;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.iot.lemon.model.SysUser;
import com.iot.lemon.service.SysUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import top.ibase4j.core.Constants;
import top.ibase4j.core.Constants.MSGCHKTYPE;
import top.ibase4j.core.base.AppBaseController;
import top.ibase4j.core.exception.LoginException;
import top.ibase4j.core.support.Assert;
import top.ibase4j.core.support.http.SessionUser;
import top.ibase4j.core.support.security.coder.HmacCoder;
import top.ibase4j.core.util.CacheUtil;
import top.ibase4j.core.util.InstanceUtil;
import top.ibase4j.core.util.PropertiesUtil;
import top.ibase4j.core.util.SecurityUtil;

/**
 * 用户登录
 *
 * @author ShenHuaJie
 * @version 2016年5月20日 下午3:11:21
 */
@RestController
@RequestMapping("/app/")
@Api(value = "APP员工登录接口", description = "APP-员工登录接口")
public class LoginController extends AppBaseController<SysUser, SysUserService> {
    @PostMapping("login.api")
    @ApiOperation(value = "登录", produces = MediaType.APPLICATION_JSON_VALUE, notes = "" + "使用手机号+密码登录\n"
            + "登录接口需要以下参数：\n" + "1. account: 用户名，目前只支持手机号\n" + "2. password: 密码\n"
            + "3. 注意：所有接口都需要传sign参数签名和timestamp时间戳", response = SysUser.class)
    public Object login(@RequestHeader("sign") @ApiParam(value = "签名", required = true) String sign,
        @RequestHeader("timestamp") @ApiParam(value = "时间戳", required = true) Long timestamp,
        @RequestHeader(required = false) @ApiParam("微信ID，暂不支持") String openId,
        @RequestHeader(required = false) @ApiParam("极光推送ID，暂不支持") String registrationId,
        @RequestParam @ApiParam(value = "手机号", required = true) String account,
        @RequestParam @ApiParam(value = "密码", required = true) String password) {
        Map<String, Object> params = InstanceUtil.newHashMap("enable", 1);
        params.put("loginKey", account);
        List<SysUser> members = service.queryList(params);
        SysUser sysUser = members.isEmpty() ? null : members.get(0);

        if (sysUser == null) {
            throw new LoginException("手机号或密码错误.");
        } else {
            if (SecurityUtil.encryptPassword(password).equals(sysUser.getPassword())) {
                String token = SecurityUtil.initHmacKey(HmacCoder.MD5);
                String tokenKey = SecurityUtil.encryptMd5(token);
                CacheUtil.getCache().set(Constants.TOKEN_KEY + tokenKey,
                    new SessionUser(sysUser.getId(), sysUser.getUserName(), sysUser.getPhone(), false),
                    PropertiesUtil.getInt("APP-TOKEN-EXPIRE", 60 * 60 * 24 * 7));
                sysUser.setToken(token);
                sysUser.setPassword(null);
                service.update(sysUser);

                return setSuccessModelMap(sysUser);
            } else {
                throw new LoginException("手机号或密码错误.");
            }
        }
    }

    @PostMapping("logout.api")
    @ApiOperation(value = "APP会员登出", produces = MediaType.APPLICATION_JSON_VALUE)
    public Object logout(@RequestHeader("sign") @ApiParam(value = "签名", required = true) String sign,
        @RequestHeader("timestamp") @ApiParam(value = "时间戳", required = true) Long timestamp,
        @RequestHeader("token") @ApiParam(value = "token", required = true) String token, HttpServletRequest request) {
        Assert.notNull(token, "ACCOUNT");
        if (StringUtils.isNotBlank(token)) {
            String tokenKey = SecurityUtil.encryptMd5(token);
            CacheUtil.getCache().del(Constants.TOKEN_KEY + tokenKey);
        }
        ModelMap modelMap = new ModelMap();
        return setSuccessModelMap(modelMap);
    }

    @PostMapping("updatePwd.api")
    @ApiOperation(value = "修改密码", produces = MediaType.APPLICATION_JSON_VALUE, notes = "" + "接口需要以下4个参数：\n"
            + "1. account: 用户名，目前只支持手机号\n" + "2. password: 密码\n" + "3. authCode: 手机短信验证码(通过/app/msg.api发送短信验证码)\n"
            + "4. 注意：所有接口都需要传sign参数签名和timestamp时间戳", response = SysUser.class)
    public Object updatePwd(@RequestHeader("sign") @ApiParam(value = "签名", required = true) String sign,
        @RequestHeader("timestamp") @ApiParam(value = "时间戳", required = true) Long timestamp,
        @RequestHeader("token") @ApiParam(value = "token", required = true) String token,
        @RequestParam @ApiParam(value = "手机号", required = true) String account,
        @RequestParam @ApiParam(value = "密码", required = true) String password,
        @RequestParam @ApiParam(value = "手机验证码", required = true) String authCode) throws Exception {
        String authCodeOnServer = (String)CacheUtil.getCache().get(MSGCHKTYPE.CHGPWD + account);
        if (!authCode.equals(authCodeOnServer)) {
            throw new IllegalArgumentException("手机验证码错误");
        }

        Map<String, Object> params = InstanceUtil.newHashMap("loginKey", account);
        List<?> members = service.queryList(params);
        SysUser member = members.isEmpty() ? null : (SysUser)members.get(0);

        if (member == null) {
            throw new IllegalArgumentException("手机号还没有注册.");
        } else {
            member.setPassword(SecurityUtil.encryptPassword(password));
            service.update(member);
            return setSuccessModelMap();
        }
    }
}
